package com.magic.service.seed;

import java.math.BigDecimal;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.magic.auth.TokenUtil;
import com.magic.entity.game.Game;
import com.magic.entity.game.GameHistory;
import com.magic.entity.user.Flower;
import com.magic.entity.user.User;
import com.magic.entity.user.UserGame;
import com.magic.repository.IFlowerRepository;
import com.magic.repository.IGameHistoryRepository;
import com.magic.repository.IGameRepository;
import com.magic.repository.IUserGameRepository;
import com.magic.result.Result;
import com.magic.service.user.UserService;
import com.magic.time.CountDown;
import com.magic.vo.PlayVo;
import com.magic.websocket.handle.DefaultWebSocketHander;
import com.magic.websocket.push.MessageVo;

/**
 * ClassName: PlayService <br/>
 * Function: 游戏动作. <br/>
 * date: 2018年10月24日 下午5:18:31 <br/>
 * 
 * @author lishuai11
 * @version
 * @since JDK 1.8
 */
@Service("playService")
public class PlayService {

	private static final Logger logger = LoggerFactory.getLogger(PlayService.class);

	@Autowired
	private IUserGameRepository userGameRepository;

	@Autowired
	private IGameHistoryRepository gameHistoryRepository;

	@Autowired
	private IGameRepository gameRepository;

	@Autowired
	private IFlowerRepository flowerRepository;

	@Autowired
	private UserService userService;

	@Transactional
	public synchronized Result seed(PlayVo playVo, String token) {
		try {
			if (!TokenUtil.resourceAudit(token, playVo.getUserId())) {
				return Result.fail(Result.CLIENT_ERROR, "Authorization is not valid  | userId is not valid");
			}
			User currentUser = userService.findOne(playVo.getUserId());
			if (currentUser == null) {
				return Result.fail(Result.CLIENT_ERROR, "非法userId");
			}
			Game game = gameRepository.findOne(playVo.getGameId());
			if (game == null) {
				return Result.fail(Result.CLIENT_ERROR, "非法gameId");
			}
			if (game.getEnd()) {
				return Result.fail(Result.CLIENT_ERROR, "游戏结束,请参与其他游戏");
			}
			Flower currentUserFlower = findFlowerByUserId(playVo.getUserId());
			if (currentUserFlower.getRechargeSeed().compareTo(playVo.getInputSeed()) < 0) {
				return Result.fail(Result.MONEY_ERROR, "充值花种不足");
			} else {
				// 均分收益在游戏历史前面
				UserGame userGame = avgInputSeed(playVo.getInputSeed(), currentUserFlower, currentUser, game);
				gameHistory(game, playVo.getInputSeed(), currentUser);
				CountDown.updateMapId(game);
				return Result.success("成功", userGame);
			}
		} catch (Exception e) {
			logger.error("PlayService.seed()方法异常{}:{}", e.getMessage(), e);
			return Result.fail(Result.SERVER_ERROR, "服务器异常");
		}
	}

	public void gameHistory(Game game, BigDecimal inputSeed, User currentUser) throws Exception {
		game.setBonus(
				game.getBonus().add(inputSeed.multiply(new BigDecimal(0.45)).setScale(2, BigDecimal.ROUND_HALF_UP)));
		game.setInputSeeds(game.getInputSeeds().add(inputSeed));
		game.setNeedPrice(game.getNeedPrice().add(new BigDecimal("0.1")));
		GameHistory history = new GameHistory(game.getGameId(), currentUser.getUserId(), currentUser.getMobile(),
				currentUser.getNickName(), currentUser.getCity(), inputSeed);
		history = gameHistoryRepository.save(history);
		MessageVo messageVo = new MessageVo(game.getGameId(), currentUser.getMobile(), currentUser.getNickName(),
				currentUser.getCity(), inputSeed, game.getNeedPrice(), game.getBonus(), game.getInputSeeds());
		JSONObject jsonObject = (JSONObject) JSON.toJSON(messageVo);
		DefaultWebSocketHander.sendMessageToGame(jsonObject.toJSONString());
		game = gameRepository.save(game);
	}

	public UserGame avgInputSeed(BigDecimal inputSeed, Flower currentUserFlower, User currentUser, Game game) {
		currentUserFlower.setRechargeSeed(currentUserFlower.getRechargeSeed().subtract(inputSeed));
		UserGame currentUserGame = findUserGameByUserIdAndGameId(currentUser.getUserId(), game.getGameId());
		if (currentUserGame == null) {
			currentUserGame = new UserGame(currentUser.getUserId(), game.getGameId(), game.getName(), game.getDetail(),
					game.getImage(), inputSeed);
		} else {
			currentUserGame.setUserInputs(currentUserGame.getUserInputs().add(inputSeed));
		}
		List<GameHistory> history = findHistoryGroupByUserId();
		BigDecimal earn = new BigDecimal("0.00");
		if (history != null && !history.isEmpty()) {
			earn = inputSeed.multiply(new BigDecimal(0.45));
			earn = earn.divide(new BigDecimal(history.size()), 2, BigDecimal.ROUND_HALF_UP);
			Flower flower;
			UserGame userGame;
			for (GameHistory gameHistory : history) {
				if (currentUserFlower.getUserId() == gameHistory.getUserId()) {
					currentUserFlower.setEarnSeed(currentUserFlower.getEarnSeed().add(earn));
					currentUserFlower
							.setAllSeed(currentUserFlower.getRechargeSeed().add(currentUserFlower.getEarnSeed()));
					flowerRepository.save(currentUserFlower);
					currentUserGame.setUserReceiver(currentUserGame.getUserReceiver().add(earn));
					currentUserGame = userGameRepository.save(currentUserGame);
				} else {
					flower = findFlowerByUserId(gameHistory.getUserId());
					flower.setEarnSeed(flower.getEarnSeed().add(earn));
					flower.setAllSeed(flower.getEarnSeed().add(flower.getRechargeSeed()));
					flowerRepository.save(flower);
					userGame = findUserGameByUserIdAndGameId(gameHistory.getUserId(), gameHistory.getGameId());
					userGame.setUserReceiver(userGame.getUserReceiver().add(earn));
					userGameRepository.save(userGame);
				}
			}
		}
		return currentUserGame;
	}

	public UserGame findUserGameByUserIdAndGameId(int userId, int gameId) {
		List<UserGame> list = userGameRepository.findByUserIdAndGameId(userId, gameId);
		if (list != null && !list.isEmpty()) {
			return list.get(0);
		} else {
			return null;
		}
	}

	public Flower findFlowerByUserId(int userId) {
		List<Flower> flowers = flowerRepository.findByUserId(userId);
		if (flowers != null && !flowers.isEmpty()) {
			return flowers.get(0);
		}
		return null;
	}

	public List<GameHistory> findHistoryGroupByUserId() {
		return gameHistoryRepository.findGroupByUserId();
	}

}
